package com.youkeyi.ddy.cloud.basic.pub.position.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.youkeyi.ddy.cloud.basic.pub.mapping.entity.SysMapping;
import com.youkeyi.ddy.cloud.basic.pub.mapping.param.BusinessDeleteParam;
import com.youkeyi.ddy.cloud.basic.pub.mapping.param.BusinessQueryParam;
import com.youkeyi.ddy.cloud.basic.pub.mapping.service.SysMappingService;
import com.youkeyi.ddy.cloud.basic.pub.organization.entity.SysOrganization;
import com.youkeyi.ddy.cloud.basic.pub.organization.service.SysOrganizationService;
import com.youkeyi.ddy.cloud.basic.pub.position.entity.SysPosition;
import com.youkeyi.ddy.cloud.basic.pub.position.service.SysPositionService;
import com.youkeyi.ddy.cloud.common.api.basic.pub.organization.dto.PublicOrganizationListItemCloudDto;
import com.youkeyi.ddy.cloud.common.api.basic.pub.position.PublicPositionCloudService;
import com.youkeyi.ddy.cloud.common.api.basic.pub.position.dto.PublicPositionListCloudDto;
import com.youkeyi.ddy.cloud.common.api.basic.pub.position.dto.PublicPositionListItemCloudDto;
import com.youkeyi.ddy.cloud.common.api.basic.pub.position.param.PublicPositionCreateCloudParam;
import com.youkeyi.ddy.cloud.common.api.basic.pub.position.param.PublicPositionDeleteCloudParam;
import com.youkeyi.ddy.cloud.common.api.basic.pub.position.param.PublicPositionQueryCloudParam;
import com.youkeyi.ddy.cloud.common.api.basic.pub.position.param.PublicPositionUpdateCloudParam;
import com.youkeyi.ddy.cloud.common.constant.YoukeyiDdyCloudBasicPublicConstant;
import com.youkeyi.ddy.cloud.common.enums.ResponseCodeEnum;
import com.youkeyi.ddy.cloud.common.response.ResponseContent;
import com.youkeyi.ddy.cloud.common.utils.SimpleUUidUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 岗位（角色）表 前端控制器
 * </p>
 *
 * @author xiawang.liu
 * @since 2024-02-19
 */
@Service
public class SysPositionController implements PublicPositionCloudService {

    @Autowired
    private SysPositionService sysPositionService;
    @Autowired
    private SysMappingService sysMappingService;
    @Autowired
    private SysOrganizationService sysOrganizationService;

    @Override
    public PublicPositionListCloudDto query(PublicPositionQueryCloudParam param) {
        PublicPositionListCloudDto dto = new PublicPositionListCloudDto();
        if (null == param) {
            dto.setErrorMessage(ResponseCodeEnum.PARAMETER_ILLEGAL.getMessage());
            return dto;
        }

        if (CollectionUtils.isNotEmpty(param.getPositionPrimaryKeys())) {
            param.getPositionPrimaryKeys().removeAll(Collections.singleton(null));
        }
        if (CollectionUtils.isNotEmpty(param.getCorpKeys())) {
            param.getCorpKeys().removeAll(Collections.singleton(null));
        }
        if (CollectionUtils.isNotEmpty(param.getCodes())) {
            param.getCodes().removeAll(Collections.singleton(null));
        }
        if (CollectionUtils.isNotEmpty(param.getNames())) {
            param.getNames().removeAll(Collections.singleton(null));
        }
        if (CollectionUtils.isNotEmpty(param.getOrganizationKeys())) {
            param.getOrganizationKeys().removeAll(Collections.singleton(null));
        }

        QueryWrapper<SysPosition> wrapper = new QueryWrapper<>();
        wrapper.lambda()
                .in(CollectionUtils.isNotEmpty(param.getPositionPrimaryKeys()), SysPosition::getPrimaryKey, param.getPositionPrimaryKeys())
                .in(CollectionUtils.isNotEmpty(param.getCorpKeys()), SysPosition::getCorpKey, param.getCorpKeys())
                .in(CollectionUtils.isNotEmpty(param.getNames()), SysPosition::getName, param.getNames())
                .like(StringUtils.isNotBlank(param.getNameFuzzy()), SysPosition::getName, param.getNameFuzzy())
                .in(CollectionUtils.isNotEmpty(param.getCodes()), SysPosition::getCode, param.getCodes())
                .in(CollectionUtils.isNotEmpty(param.getOrganizationKeys()), SysPosition::getOrganizationKey, param.getOrganizationKeys())
                .ne(SysPosition::getIsDeleted, YoukeyiDdyCloudBasicPublicConstant.SYSTEM_YES_OR_NO_YES.value())
        ;

        Page<SysPosition> page = new Page<>();
        if (null != param.getCurrentPage() && null != param.getPageSize()) {
            page.setCurrent(param.getCurrentPage());
            page.setSize(param.getPageSize());
        } else {
            page.setCurrent(1);
            page.setSize(99999999);
        }
        Page<SysPosition> positionList = sysPositionService.page(page, wrapper);
        if (CollectionUtils.isNotEmpty(positionList.getRecords())) {
            dto.setTotal(positionList.getTotal());

            // 查询映射数据
            BusinessQueryParam queryMappingParam = new BusinessQueryParam();
            queryMappingParam.setMappingType(YoukeyiDdyCloudBasicPublicConstant.PUBLIC_MAPPING_TYPE_POSITION_AUTH.value());
            queryMappingParam.setKeyType(YoukeyiDdyCloudBasicPublicConstant.PUBLIC_MAPPING_KEY_TYPE_SOURCE.value());
            queryMappingParam.setKeys(positionList.getRecords().stream().map(SysPosition::getPrimaryKey).collect(Collectors.toList()));
            Map<String, List<String>> authKeysMap = new HashMap<>();
            List<SysMapping> sysMappings = sysMappingService.businessQuery(queryMappingParam);
            if (CollectionUtils.isNotEmpty(sysMappings)) {
                sysMappings.forEach(mapping -> {
                    if (!authKeysMap.containsKey(mapping.getSourceKey())) {
                        authKeysMap.put(mapping.getSourceKey(), new ArrayList<>());
                    }
                    authKeysMap.get(mapping.getSourceKey()).add(mapping.getTargetKey());
                });
            }

            Map<String, SysOrganization> organizationMap = new HashMap<>();
            if (param.getNeedOrganization()) {
                List<String> organizationKeys = positionList.getRecords().stream().map(SysPosition::getOrganizationKey).collect(Collectors.toList());

                QueryWrapper<SysOrganization> organizationQueryWrapper = new QueryWrapper<>();
                organizationQueryWrapper.lambda()
                        .in(SysOrganization::getPrimaryKey, organizationKeys)
                ;
                List<SysOrganization> organizations = sysOrganizationService.list(organizationQueryWrapper);
                if (CollectionUtils.isNotEmpty(organizations)) {
                    organizationMap.putAll(organizations.stream().collect(Collectors.toMap(SysOrganization::getPrimaryKey, Function.identity())));
                }
            }


            List<PublicPositionListItemCloudDto> items = new ArrayList<>();
            positionList.getRecords().forEach(position -> {
                PublicPositionListItemCloudDto item = new PublicPositionListItemCloudDto();
                item.setPositionPrimaryKey(position.getPrimaryKey());
                item.setCorpKey(position.getCorpKey());
                item.setName(position.getName());
                item.setCode(position.getCode());
                item.setOrganizationKey(position.getOrganizationKey());
                item.setDesc(position.getDesc());
                item.setIsDeleted(position.getIsDeleted());
                item.setIsDeletedName(YoukeyiDdyCloudBasicPublicConstant.SYSTEM_YES_OR_NO.getName(item.getIsDeleted()));
                item.setCreateTime(position.getCreateTime() != null ? position.getCreateTime().getTime() : null);
                item.setCreateUserKey(position.getCreateUserKey());
                item.setCreateUserName(position.getCreateUserName());
                item.setUpdateTime(position.getUpdateTime() != null ? position.getUpdateTime().getTime() : null);
                item.setUpdateUserKey(position.getUpdateUserKey());
                item.setUpdateUserName(position.getUpdateUserName());
                if (authKeysMap.containsKey(position.getPrimaryKey())) {
                    item.setAuthKeys(authKeysMap.get(position.getPrimaryKey()));
                }
                if (organizationMap.containsKey(position.getOrganizationKey())) {
                    SysOrganization sysOrganization = organizationMap.get(position.getOrganizationKey());
                    PublicOrganizationListItemCloudDto organization = new PublicOrganizationListItemCloudDto();
                    organization.setOrganizationPrimaryKey(sysOrganization.getPrimaryKey());
                    organization.setCorpKey(sysOrganization.getCorpKey());
                    organization.setName(sysOrganization.getName());
                    organization.setCode(sysOrganization.getCode());
                    organization.setLevel(sysOrganization.getLevel());
                    organization.setType(sysOrganization.getType());
                    organization.setParentKey(sysOrganization.getParentKey());
                    organization.setPath(sysOrganization.getPath());
                    organization.setIsDeleted(sysOrganization.getIsDeleted());
                    organization.setCreateUserKey(sysOrganization.getCreateUserKey());
                    organization.setCreateUserName(sysOrganization.getCreateUserName());
                    organization.setCreateTime(sysOrganization.getCreateTime() != null ? sysOrganization.getCreateTime().getTime() : null);
                    organization.setUpdateUserKey(sysOrganization.getUpdateUserKey());
                    organization.setUpdateUserName(sysOrganization.getUpdateUserName());
                    organization.setUpdateTime(sysOrganization.getUpdateTime() != null ? sysOrganization.getUpdateTime().getTime() : null);
                    item.setOrganization(organization);
                }
                items.add(item);
            });
            dto.setRows(items);
        }
        dto.setSuccessMessage(ResponseCodeEnum.SUCCESS.getMessage());
        return dto;
    }

    @Override
    public ResponseContent create(PublicPositionCreateCloudParam param) {
        ResponseContent rc = new ResponseContent();
        if (null == param || StringUtils.isBlank(param.getCorpKey())
                || StringUtils.isBlank(param.getOrganizationKey()) || StringUtils.isBlank(param.getName())) {
            rc.setErrorMessage(ResponseCodeEnum.PARAMETER_ILLEGAL.getMessage());
            return rc;
        }
        SysPosition position = new SysPosition();
        position.setPrimaryKey(SimpleUUidUtils.getUuid());
        position.setCorpKey(param.getCorpKey());
        position.setName(param.getName());
        position.setCode(StringUtils.isNotBlank(param.getCode()) ? param.getCode() : String.format("PS-%s", System.currentTimeMillis()));
        position.setOrganizationKey(param.getOrganizationKey());
        position.setDesc(param.getDesc());
        position.setIsDeleted(YoukeyiDdyCloudBasicPublicConstant.SYSTEM_YES_OR_NO_NO.value());
        position.setCreateUserKey(param.getCreateUserKey());
        position.setCreateUserName(param.getCreateUserName());
        position.setCreateTime(new Date());
        boolean save = sysPositionService.save(position);
        if (!save) {
            rc.setErrorMessage(ResponseCodeEnum.FAIL.getMessage());
            return rc;
        }

        // 服务数据录入
        if (CollectionUtils.isNotEmpty(param.getAuthKeys())) {
            List<SysMapping> serverCreateParams = new ArrayList<>();
            param.getAuthKeys().forEach(authPrimaryKey -> {
                SysMapping serverMapping = new SysMapping();
                serverMapping.setPrimaryKey(SimpleUUidUtils.getUuid());
                serverMapping.setMappingType(YoukeyiDdyCloudBasicPublicConstant.PUBLIC_MAPPING_TYPE_POSITION_AUTH.value());
                serverMapping.setSourceKey(position.getPrimaryKey());
                serverMapping.setTargetKey(authPrimaryKey);
                serverMapping.setCreateUserKey(param.getCreateUserKey());
                serverMapping.setCreateUserName(param.getCreateUserName());
                serverCreateParams.add(serverMapping);
            });
            sysMappingService.businessCreate(serverCreateParams);
        }

        rc.setSuccessMessage(ResponseCodeEnum.SUCCESS.getMessage());
        rc.setKey(position.getPrimaryKey());
        return rc;
    }

    @Override
    public ResponseContent update(PublicPositionUpdateCloudParam param) {
        ResponseContent rc = new ResponseContent();
        if (null == param || StringUtils.isBlank(param.getPositionPrimaryKey())) {
            rc.setErrorMessage(ResponseCodeEnum.PARAMETER_ILLEGAL.getMessage());
            return rc;
        }

        UpdateWrapper<SysPosition> wrapper = new UpdateWrapper<>();
        wrapper.lambda()
                .eq(SysPosition::getPrimaryKey, param.getPositionPrimaryKey());
        SysPosition position = new SysPosition();
        position.setCorpKey(param.getCorpKey());
        position.setName(param.getName());
        position.setCode(param.getCode());
        position.setOrganizationKey(param.getOrganizationKey());
        position.setDesc(param.getDesc());
        position.setUpdateUserKey(param.getUpdateUserKey());
        position.setUpdateUserName(param.getUpdateUserName());
        position.setUpdateTime(new Date());
        boolean save = sysPositionService.update(position, wrapper);
        rc.setSuccessMessage(ResponseCodeEnum.SUCCESS.getMessage());
        if (!save) {
            rc.setErrorMessage(ResponseCodeEnum.FAIL.getMessage());
            return rc;
        }

        // 删除映射数据
        BusinessDeleteParam deleteMappingParam = new BusinessDeleteParam();
        deleteMappingParam.setMappingType(YoukeyiDdyCloudBasicPublicConstant.PUBLIC_MAPPING_TYPE_POSITION_AUTH.value());
        deleteMappingParam.setKeyType(YoukeyiDdyCloudBasicPublicConstant.PUBLIC_MAPPING_KEY_TYPE_SOURCE.value());
        deleteMappingParam.setKeys(Collections.singletonList(param.getPositionPrimaryKey()));
        sysMappingService.businessDelete(deleteMappingParam);
        // 重新加入映射数据
        if (CollectionUtils.isNotEmpty(param.getAuthKeys())) {
            List<SysMapping> serverCreateParams = new ArrayList<>();
            param.getAuthKeys().forEach(authPrimaryKey -> {
                SysMapping serverMapping = new SysMapping();
                serverMapping.setPrimaryKey(SimpleUUidUtils.getUuid());
                serverMapping.setMappingType(YoukeyiDdyCloudBasicPublicConstant.PUBLIC_MAPPING_TYPE_POSITION_AUTH.value());
                serverMapping.setSourceKey(param.getPositionPrimaryKey());
                serverMapping.setTargetKey(authPrimaryKey);
                serverMapping.setCreateUserKey(param.getUpdateUserKey());
                serverMapping.setCreateUserName(param.getUpdateUserName());
                serverCreateParams.add(serverMapping);
            });
            sysMappingService.businessCreate(serverCreateParams);
        }
        return rc;
    }

    @Override
    public ResponseContent delete(PublicPositionDeleteCloudParam param) {
        ResponseContent rc = new ResponseContent();
        if (null == param || CollectionUtils.isEmpty(param.getPositionPrimaryKeys())) {
            rc.setErrorMessage(ResponseCodeEnum.PARAMETER_ILLEGAL.getMessage());
            return rc;
        }
        UpdateWrapper<SysPosition> wrapper = new UpdateWrapper<>();
        wrapper.lambda()
                .in(SysPosition::getPrimaryKey, param.getPositionPrimaryKeys());

        SysPosition position = new SysPosition();
        position.setIsDeleted(YoukeyiDdyCloudBasicPublicConstant.SYSTEM_YES_OR_NO_YES.value());
        position.setUpdateUserKey(param.getUpdateUserKey());
        position.setUpdateUserName(param.getUpdateUserName());
        position.setUpdateTime(new Date());
        boolean save = sysPositionService.update(position, wrapper);
        rc.setSuccessMessage(ResponseCodeEnum.SUCCESS.getMessage());
        if (!save) {
            rc.setErrorMessage(ResponseCodeEnum.FAIL.getMessage());
        }

        // 删除映射数据
        BusinessDeleteParam deleteMappingParam = new BusinessDeleteParam();
        deleteMappingParam.setMappingType(YoukeyiDdyCloudBasicPublicConstant.PUBLIC_MAPPING_TYPE_POSITION_AUTH.value());
        deleteMappingParam.setKeyType(YoukeyiDdyCloudBasicPublicConstant.PUBLIC_MAPPING_KEY_TYPE_SOURCE.value());
        deleteMappingParam.setKeys(param.getPositionPrimaryKeys());
        sysMappingService.businessDelete(deleteMappingParam);
        return rc;
    }
}
